-- local card = require "card"
-- local skynet = require "skynet"
-- 牌的处理

local Player = class("Player")
--手牌类型
local HTYPE = {
	CHI 	= 1,
	JIAO	= 2,
	PENG	= 3,
	WEI 	= 4,
	PAO 	= 5,
	TI 		= 6,
	JIANG	= 7,
	KAN		= 8,
}
function Player:ctor(rule)

	self.set = {} --玩家手牌
	self.kan = {} --坎牌
	self.wei = {} --偎牌
	self.peng = {} --碰牌
	self.chi = {} --吃
	self.ti = {} --提牌
	self.pao = {} --跑牌
	self.not_peng = {} --忍碰
	self.action_can_do = {}	 --玩家可以进行的动作：吃碰胡(偎,跑等为自动)
	self.play_front = {} --已丢出的牌
	self.deal_cards = {} --所有已操作的门子
	self.this_turn_get = nil --摸的牌
	self.recent_play = nil --这轮出的牌
	self.totalHuxi = 0 --总胡息
	self.frontHuxi = 0 --明面上的胡息
	self.tbMenzi = {} --最后结果的门子
	self.endHuxi = 0 --结束时胡息

	self.playerid = nil --玩家id
	self.seatid = nil --座位id

	self.rule = rule
end

function Player:get_set()
	return self.set
end
function Player:get_ti()
	return self.ti
end
function Player:get_pao()
	return self.pao
end
function Player:get_kan()
	return self.kan
end

--所有玩家手牌包括坎
function Player:get_hand_set()
	local set = {}
	for _,v in pairs(self.set) do
		table.insert(set,v)
	end
	for k,v in pairs(self.kan) do
		self.rule:add(set,v)
	end
	return set
end

function Player:get_deal_cards()
	return self.deal_cards
end

function Player:get_play_front()
	return self.play_front
end

function Player:set_this_turn_get(c)
	self.this_turn_get = c
end

--摸到的牌
function Player:get_this_turn_get()
	return self.this_turn_get
end

--清除当前提摸到的牌与出的牌
function Player:update_player_cards()
	self.recent_play = nil
	self.this_turn_get = nil
end

function Player:set_recent_play(c)
	if not self.recent_play then
		--skynet.error("recent_play is nil")
	end
	self.recent_play = c
end

function Player:get_recent_play()
	return self.recent_play
end

function Player:set_action_can_do(t)	
	self.action_can_do = t
end

function Player:set_deal_cards(_type,cards)	
	if _type == HTYPE.CHI then
		table.insert(self.deal_cards,{_type=_type ,cards=cards })	
	elseif _type == HTYPE.PENG then
		table.insert(self.deal_cards,{_type=_type ,cards=cards })	
	elseif _type == HTYPE.WEI then
		table.insert(self.deal_cards,{_type=_type ,cards=cards })	
	elseif _type == HTYPE.PAO then
		local is_del = false
		for k,v in pairs(self.deal_cards) do
			--skynet.error("v.cards[1] == cards[1]",inspect(v.cards)  , inspect(cards),inspect(self.deal_cards))
			if v.cards[1] == cards[1] and ( HTYPE.WEI == v._type or HTYPE.PENG == v._type) then
				table.remove(self.deal_cards,k)
				table.insert(self.deal_cards,{_type=_type ,cards=cards })	
				is_del = true
				break
			end
		end
		if not is_del then
			table.insert(self.deal_cards,{_type=_type ,cards=cards })
		end
	elseif _type == HTYPE.TI then
		local is_del = false
		for k,v in pairs(self.deal_cards) do
			if v.cards[1] == cards[1] and ( HTYPE.WEI == v._type or HTYPE.PENG == v._type) then
				table.remove(self.deal_cards,k)
				table.insert(self.deal_cards,{_type=_type ,cards=cards })
				is_del = true
				break
			end
		end
		if not is_del then
			table.insert(self.deal_cards,{_type=_type ,cards=cards })	
		end
	else
		return 
	end
end

function Player:get_action_can_do()
	return self.action_can_do
end

--整理手牌
function Player:arrange_set()	
	--把坎牌放到坎牌区
	local card_nums = self.rule:get_all_value_nums(self.set)
	for k,v in pairs(card_nums) do
		if v == 3 then
			self.rule:drop(self.set,k)
			self.rule:drop(self.set,k)
			self.rule:drop(self.set,k)
			table.insert(self.kan,{k,k,k})
		end
	end
end

--初始化手牌
function Player:initCards(t)
	self.set = t
end

function Player:is_valid_play(c)
	--skynet.error("is_valid_play",c,self.this_turn_get,inspect(self.set))
	if 	self.this_turn_get == c or self.rule:has(self.set,c) then
		return true
	end
	return false
end

function Player:auto_play()
	--skynet.error("auto_play",self.this_turn_get)
	if self.this_turn_get then
		local c = self.this_turn_get
		--self.this_turn_get = nil
		self.recent_play = c
		--table.insert(self.play_front,c)
		return c
	else
		self.rule:sort_card(self.set)
		local c = table.remove(self.set)
		
		self.recent_play = c
		--table.insert(self.play_front,c)
		return self.recent_play
	end
end

--确认出牌
function Player:confirm_play(c)
	--skynet.error("confirm_play",self.recent_play,self.this_turn_get,c)
	if self.recent_play == c then
		table.insert(self.play_front,c)
		self.recent_play = nil
	elseif self.this_turn_get == c then
		table.insert(self.play_front,c)
		self.this_turn_get = nil
	else
		--skynet.error("第一回合需要确认 ++")
		self.rule:drop(self.set,c)
	end
	return c
end

--是否能跑
function Player:check_pao_card(c,isOther)
	for _,v in ipairs(self.kan) do
		if v[1] == c then
			return true
		end
	end
	for _,v in ipairs(self.wei) do
		if v[1] == c then
			return true
		end
	end
	if isOther then 
		--别人出的牌，碰不能跑
		return false
	end
	for _,v in ipairs(self.peng) do
		if v[1] == c then
			return true
		end
	end
end

--是否能提
function Player:check_ti_card(card)
	-- print("check_ti_card___",self.this_turn_get,card,self.kan)
	if self.this_turn_get then
		for _,v in ipairs(self.kan) do
			if v[1] == self.this_turn_get then
				print("ti__kan___",self.kan,self.this_turn_get)
				return true
			end
		end
	end

	if self.this_turn_get then
		for _,v in ipairs(self.wei) do
			if v[1] == self.this_turn_get then
				print("ti__wei___",self.kan,self.this_turn_get)
				return true
			end
		end
	end

	local card_nums = self.rule:get_all_value_nums(self.set)
	for _,v in pairs(card_nums) do
		if v == 4 then
			print("ti__set___",self.set,self.this_turn_get)
			return true
		end
	end
end

--是否能偎
function Player:check_wei_card(c)
	local card_nums = self.rule:get_all_value_nums(self.set)
	if card_nums[c] == 2 then
		return true
	end
end

--是否能碰
function Player:check_peng_card(c)
	local card_nums = self.rule:get_all_value_nums(self.set)
	if card_nums[c] == 2 then
		return true
	end
end

--返回偎牌结果
function Player:wei_card(c)
	if self.this_turn_get ~= c then
		--skynet.error("wei_card is error",c,self.this_turn_get)
		return
	end
	local card_nums = self.rule:get_all_value_nums(self.set)
	if card_nums[c] ~= 2 then
		--skynet.error("wei_card is error, card_nums error",self.this_turn_get,c,card_nums[c])
		return
	end
	self.rule:drop(self.set,c)
	self.rule:drop(self.set,c)
	local t = {c,c,c}
	table.insert(self.wei,t)
	self.this_turn_get = nil
	--ret = t
	self:set_deal_cards(HTYPE.WEI,t)
	return t
end

--是否能胡
function Player:check_hu_card(c)

	local cards = {}
	for k,v in pairs(self.set) do 		
		table.insert(cards,v)	
	end		
	-- print("_____check_hu_card____cards___",cards,c)
	local tbMenzi,curHuxi = self:hu_end_card(c)	

	local card_nums = self.rule:get_all_value_nums(self.set)
	if card_nums[c] == 2 then
		--碰胡
		print("_________碰胡________",c)
		local tbPeng = {c,c,c}
		local pengHuxi = self:get_mezi_huxi(HTYPE.PENG,tbPeng)
		local cHuxi = curHuxi + pengHuxi
		self.rule:drop(cards,c)
		self.rule:drop(cards,c)
		local bHu,huxi,tbMen = self.rule:checkHu(cards,nil,cHuxi,#tbMenzi+1)
		if bHu then 
			local menzi = {}
			menzi.hand = tbPeng
			menzi.type = HTYPE.PENG
			menzi.huxi = self:get_mezi_huxi(menzi.type,menzi.hand)
			menzi.target_card = 1
			table.insert(tbMenzi,menzi)
			for k,v in pairs(tbMen) do 
				local menzi = {}
				menzi.hand = table.copy(v)
				menzi.type = HTYPE.CHI
				if #v == 2 then 
					menzi.type = HTYPE.JIANG
				end
				menzi.huxi = self:get_mezi_huxi(menzi.type,menzi.hand)
				table.insert(tbMenzi,menzi)
			end
			self.tbMenzi = tbMenzi
			self.endHuxi = huxi
			-- print("____11111_______self.tbMenzi______",self.tbMenzi)
			return bHu,huxi,tbMen		
		end
	end	

	cards = {}
	for k,v in pairs(self.set) do 		
		table.insert(cards,v)	
	end	
	local bHu,huxi,tbMen = self.rule:checkHu(cards,c,curHuxi,#tbMenzi)
	local target_card
	if bHu then 
		print("_________吃胡________",c)
		for k,v in pairs(tbMen) do 	
			local menzi = {}
			menzi.hand = table.copy(v)
			menzi.type = HTYPE.CHI
			if #v == 2 then 
				menzi.type = HTYPE.JIANG
			end			
			menzi.huxi = self:get_mezi_huxi(menzi.type,menzi.hand)
			if not target_card then
				for _,tc in pairs(v) do 
					if c == tc then 
						menzi.target_card = 1
						target_card = true
					end
				end
			end
			table.insert(tbMenzi,menzi)
		end
		self.tbMenzi = tbMenzi
		self.endHuxi = huxi
	end
	-- print("____2222_______self.tbMenzi______",self.tbMenzi)
	return bHu,huxi,tbMen

end

-- 获取特定类型，特定牌胡息
function Player:get_mezi_huxi(t,cards)
	local card = cards[1]
	if t == HTYPE.PENG then		-- 碰
		if card <= 0x1a then
			return 1
		else
			return 3
		end
	elseif t == HTYPE.WEI or t == HTYPE.KAN then	-- 偎
		if card <= 0x1a then
			return 3
		else
			return 6
		end
	elseif t == HTYPE.PAO then	-- 跑
		if card <= 0x1a then
			return 6
		else
			return 9
		end
	elseif t == HTYPE.TI then	-- 提
		if card <= 0x1a then
			return 9
		else
			return 12
		end
	elseif t == HTYPE.CHI then 
		--顺子123,27a
		self.rule:sortCards(cards)
		if (cards[1]==0x11 and cards[2]==0x12 and cards[3]==0x13) or
			(cards[1]==0x12 and cards[2]==0x17 and cards[3]==0x1a) then
			return 3 
		elseif (cards[1]==0x21 and cards[2]==0x22 and cards[3]==0x23) or
				(cards[1]==0x22 and cards[2]==0x27 and cards[3]==0x2a)	then
			return 6 	
		end
	end
	return 0
end


--胡后的牌
function Player:hu_end_card(card)
	local tb = {}	
	local totalHuxi = 0
	local lastDeal = self.deal_cards[#self.deal_cards]
	local function getMenzi(tb,groups,t)
		local menzi
		for k,v in pairs(groups) do 
			menzi = {}
			menzi.hand = table.copy(v)
			menzi.type = t
			menzi.huxi = self:get_mezi_huxi(t,menzi.hand)
			if not card and lastDeal then 
				if lastDeal._type == t then 
					local b=true
					for i,j in pairs(v) do 
						if lastDeal.cards[i] ~= j then 
							b = false
							break
						end
					end
					if b then 
						--标记胡的牌
						menzi.target_card = 1
					end
				end				
			end

			totalHuxi = totalHuxi + menzi.huxi
			table.insert(tb,menzi)
		end	
	end

	local tbMenZi = {
		{self.kan,HTYPE.KAN},
		{self.wei,HTYPE.WEI},
		{self.peng,HTYPE.PENG},
		{self.chi,HTYPE.CHI},
		{self.pao,HTYPE.PAO},
		{self.ti,HTYPE.TI},
	}
	for k,v in pairs(tbMenZi) do 
		getMenzi(tb,v[1],v[2])
	end

	-- print("_____hu menzi___",tb)
	-- print("_________set card__",self.set)
	return tb,totalHuxi
end
function Player:getKanHuxi()
	local huxi = 0 
	for k,v in pairs(self.kan) do 
		huxi = huxi + self:get_mezi_huxi(HTYPE.KAN,v)
	end
	return huxi
end

function Player:checkHuxi()
	local tbMenzi,curHuxi = self:hu_end_card()	
	-- local huxi = self.rule:getHuxi123(self.set)
	-- local totalHuxi = huxi + curHuxi
	curHuxi = curHuxi - self:getKanHuxi()
	if self.frontHuxi ~= curHuxi then 
		-- self.totalHuxi = totalHuxi
		self.frontHuxi = curHuxi --已摆出来的牌的胡息		
		return true
	end
	return false
end

function Player:checkTing()

	local tbMenzi,curHuxi = self:hu_end_card()	
	local tbRes = {}
	--吃胡
	local cards = table.copy(self.set)
	local function chiHu(cards,curhuxi,menziNum)
		local bHu,huxi,tbMen
		for card=0x11,0x1a do
			bHu,huxi,tbMen = self.rule:checkHu(cards,card,curhuxi,menziNum)
			if bHu then 
				table.insert(tbRes,card)
			end
		end
		for card=0x21,0x2a do
			bHu,huxi,tbMen = self.rule:checkHu(cards,card,curhuxi,menziNum)
			if bHu then 
				table.insert(tbRes,card)
			end
		end	
	end	
	chiHu(cards,curHuxi,#tbMenzi)

	--碰胡、偎胡
	local cards = table.copy(self.set)
	local card_nums = self.rule:get_all_value_nums(cards)
	local function pengHu(c)
		if card_nums[c] ~= 2 then
			return
		end
		--碰胡
		print("_________碰胡________")
		local tbPeng = {c,c,c}
		local pengHuxi = self:get_mezi_huxi(HTYPE.PENG,tbPeng)
		local cHuxi = curHuxi + pengHuxi
		cards = table.copy(self.set)
		self.rule:drop(cards,c)
		self.rule:drop(cards,c)
		local bHu,huxi,tbMen = self.rule:checkHu(cards,nil,cHuxi,#tbMenzi+1)
		if bHu then 
			table.insert(tbRes,c)		
		end	
	end
	for c=0x11,0x1a do
		pengHu(c)	
	end
	for c=0x21,0x2a do
		pengHu(c)	
	end

-----------------
	local function getMenzi(tb,groups,t)
		local menzi
		local totalHuxi = 0
		for k,v in pairs(groups) do 
			menzi = {}
			menzi.hand = table.copy(v)
			menzi.type = t
			menzi.huxi = self:get_mezi_huxi(t,menzi.hand)		
			totalHuxi = totalHuxi + menzi.huxi
			table.insert(tb,menzi)				
		end	
		return totalHuxi
	end	
	--提胡
	--1 改造坎碰偎的牌->ti
	local cards = table.copy(self.set)
	local card
	local tbCard
	local tbMenZi = {
		kan={self.kan,HTYPE.KAN},
		wei={self.wei,HTYPE.WEI},
		peng={self.peng,HTYPE.PENG},
		chi={self.chi,HTYPE.CHI},
		pao={self.pao,HTYPE.PAO},
		ti={self.ti,HTYPE.TI},
	}	
	local function tingTi(tbMenZi,tbCard,tbSrc,type1,type2)
		for k,v in pairs(tbSrc) do 
			tbCard = table.copy(tbSrc)
			tbTi = table.copy(self.ti)
			card = v[1]
			table.remove(tbCard,k)		
			table.insert(tbTi,{card,card,card,card})

			tbMenZi[type1][1] = tbCard
			tbMenZi[type2][1] = tbTi
			local tb = {}	
			local totalHuxi = 0			
			for k,v in pairs(tbMenZi) do 
				totalHuxi = totalHuxi + getMenzi(tb,v[1],v[2])
			end		
			local tbMenzi,curHuxi = tb,totalHuxi
			local bHu,huxi,tbMen = self.rule:checkHu(cards,nil,curHuxi,#tbMenzi)
			if bHu then 
				table.insert(tbRes,card)		
			end	
		end
	end
	tingTi(tbMenZi,tbCard,self.kan,"kan","ti")
	--跑胡
	tingTi(tbMenZi,tbCard,self.wei,"wei","pao")
	tingTi(tbMenZi,tbCard,self.peng,"peng","pao")


	-- table 去重
	function table_unique(t) 
	    local check = {};
	    local n = {};
	    for key , value in pairs(t) do
	        if not check[value] then
	            n[key] = value
	            check[value] = value
	        end
	    end
	    return n
	end 
	local res = {}
	for key , value in pairs(table_unique(tbRes)) do
	    table.insert(res,value)
	end

	print("___听牌结果__",res)
	return res

end



function Player:kan_card_nums()
	return #self.kan
end

function Player:ti_card_nums()
	local nums = 0
	local card_nums = self.rule:get_all_value_nums(self.set)
	for _,v in pairs(card_nums) do
		if v == 4 then
			nums = nums + 1
		end
	end
	return nums
end

function Player:pao_card(c)
	--skynet.error("pao",inspect(self))
	local ret = {}
	--手上有坎的情况提
	for i=1,#self.kan do
		if self.kan[i][1] == c then
			local t = table.remove(self.kan,i)
			self.rule:add(t,c)
			table.insert(self.pao,t)
			--self.this_turn_get = nil
			ret = t
			break
		end
	end
	--手上有偎的情况提
	for i=1,#self.wei do
		if self.wei[i][1] == c then
			local t = table.remove(self.wei,i)
			self.rule:add(t,c)
			table.insert(self.pao,t)
			--self.this_turn_get = nil
			ret = t
			break
		end
	end
	--手上有碰的情况提
	for i=1,#self.peng do
		if self.peng[i][1] == c then
			local t = table.remove(self.peng,i)
			self.rule:add(t,c)
			table.insert(self.pao,t)
			--self.this_turn_get = nil
			ret = t
			break
		end
	end
	self:set_deal_cards(HTYPE.PAO,ret)
	return ret
end

function Player:ti_card()
	local ret = {}
	--手上有4张牌的情况提
	local card_nums = self.rule:get_all_value_nums(self.set)	
	for k,v in pairs(card_nums) do
		if v == 4 then
			self.rule:drop(self.set,k)
			self.rule:drop(self.set,k)
			self.rule:drop(self.set,k)
			self.rule:drop(self.set,k)
			local t = {k,k,k,k}
			table.insert(self.ti,t)
			-- self.this_turn_get = nil
			self:set_deal_cards(HTYPE.TI,t)
			ret = t		
			print("______起手提______",t)	
		end		
	end
	if next(ret) then 
		return self.ti
	end
	--手上有坎的情况提
	--skynet.error("self.kan",inspect(self.kan))
	for i=1,#self.kan do
		--skynet.error("self.kan i",inspect(i),inspect(self.this_turn_get))
		if self.kan[i][1] == self.this_turn_get then
			local t = table.remove(self.kan,i)
			self.rule:add(t,self.this_turn_get)
			table.insert(self.ti,t)
			self.this_turn_get = nil
			ret = t
			break
		end
	end
	--手上有偎的情况提
	for i=1,#self.wei do
		if self.wei[i][1] == self.this_turn_get then
			local t = table.remove(self.wei,i)
			self.rule:add(t,self.this_turn_get)
			table.insert(self.ti,t)
			self.this_turn_get = nil
			ret = t
			break
		end
	end
	self:set_deal_cards(HTYPE.TI,ret)
	return ret
end

function Player:is_valid_chi(c,t)
	--skynet.error("is_valid_chi t",inspect(t),c)
	local chi_cards = self.rule:get_chi_cards(t)
	--skynet.error("is_valid_chi chi_cards",inspect(chi_cards),c)
	assert(chi_cards)

	self.rule:drop(chi_cards,c)
	local chi_card_nums = self.rule:get_all_value_nums(chi_cards)
	local set_card_nums = self.rule:get_all_value_nums(self.set)
	for k,v in pairs(chi_card_nums) do
		if v > set_card_nums[k] then
			--skynet.error("is_valid_chi 2 :", v , set_card_nums[c])
			return false
		end
	end

	return true
end


--TODO 吃的处理暂存
function Player:chi_card(c,t)
	local t1 = table.copy(t)
	local chi_cards = t1.cards
	local tb1
	local tb2
	if t1.comp then
		tb1 = t1.comp[1]
		tb2 = t1.comp[2]
	end
	self.rule:drop(chi_cards,c)
	for k,v in pairs(chi_cards) do
		self.rule:drop(self.set,v)
	end
	table.insert(self.chi,t.cards)
	self:set_deal_cards(HTYPE.CHI,t.cards)
	if tb1 then
		for k,v in pairs(tb1.cards) do
			self.rule:drop(self.set,v)
		end
		table.insert(self.chi,tb1.cards)
		self:set_deal_cards(HTYPE.CHI,tb1.cards)
	end
	if tb2 then
		for k,v in pairs(tb2.cards) do
			self.rule:drop(self.set,v)
		end
		table.insert(self.chi,tb2.cards)
		self:set_deal_cards(HTYPE.CHI,tb2.cards)
	end
	return t
end

function Player:play_card(c)
	self.recent_play = c
	if self.this_turn_get ~= c then
		self.rule:drop(self.set,c)
		self.rule:add(self.set,self.this_turn_get)
	end
	self.this_turn_get = nil
	--table.insert(self.play_front,c)
	self.action_can_do = {}
end

function Player:peng_card(c)
	local nums = self.rule:get_specify_nums(self.set,c)
	if nums < 2 then
		return
	end 
	self.rule:drop(self.set,c)
	self.rule:drop(self.set,c)

	local tb = {c,c,c}
	table.insert(self.peng,tb)

	self:set_deal_cards(HTYPE.PENG,tb)
	return tb
end


return Player